package com.sgai.zero_robot.core;

import static com.sgai.zero_robot.core.Config.*;
import static com.sgai.zero_robot.core.Protocol.getAlarmInfo;

import android.text.TextUtils;
import android.util.Log;

import com.sgai.zero_robot.core.callback.AlarmCallback;
import com.sgai.zero_robot.core.callback.BatteryCallback;
import com.sgai.zero_robot.core.callback.CameraCallback;
import com.sgai.zero_robot.core.callback.ConfigCallback;
import com.sgai.zero_robot.core.callback.LaserRangingCallback;
import com.sgai.zero_robot.core.callback.LogCallback;
import com.sgai.zero_robot.core.callback.MoveSpeedCallback;
import com.sgai.zero_robot.core.callback.RobotCallback;
import com.sgai.zero_robot.core.callback.SparkForkCallback;
import com.sgai.zero_robot.core.callback.SpeedRatioCallback;
import com.sgai.zero_robot.core.callback.SwingAngleCallback;
import com.sgai.zero_robot.core.io.RobotSerialManager;
import com.sgai.zero_robot.ui.alarm.AlarmUtils;
import com.sgai.zero_robot.utils.LogUtil;

import java.nio.charset.StandardCharsets;

public class RobotManager extends RobotManagerFactory {
    @Override
    public void handleMessage(String data) {
        LogUtil.e(TAG, "handleMessage: " + data);
        if (handler.hasMessages(timeWhat)) {
            handler.removeMessages(timeWhat);
            handler.sendEmptyMessageDelayed(timeWhat, timeDelay);
        }
        isConnect.set(true);
        if (!TextUtils.isEmpty(data)) {
            String[] split = data.split(FENHAO);
            for (String message : split) {
                if (message.startsWith(LMV)) {
                    leftSpeed = getValue(message);
                    //左侧行走速度
                    for (MoveSpeedCallback moveSpeedCallback1 : moveSpeedCallback) {
                        if (moveSpeedCallback1 != null) {
                            moveSpeedCallback1.onLeftSpeed(leftSpeed);
                        }
                    }
                } else if (message.startsWith(RMV)) {
                    rightSpeed = getValue(message);
                    //右侧行走速度
                    for (MoveSpeedCallback moveSpeedCallback1 : moveSpeedCallback) {
                        if (moveSpeedCallback1 != null) {
                            moveSpeedCallback1.onRightSpeed(rightSpeed);
                        }
                    }
                } else if (message.startsWith(FDS)) {
                    frontLaserRanging = getValue(message);
                    //前侧激光测距
                    for (LaserRangingCallback laserRangingCallback1 : laserRangingCallback) {
                        if (laserRangingCallback1 != null) {
                            laserRangingCallback1.onFrontLaserRanging(frontLaserRanging);
                        }
                    }
                } else if (message.startsWith(BDS)) {
                    backLaserRanging = getValue(message);
                    //后侧激光测距
                    for (LaserRangingCallback laserRangingCallback1 : laserRangingCallback) {
                        if (laserRangingCallback1 != null) {
                            laserRangingCallback1.onBackLaserRanging(backLaserRanging);
                        }
                    }
                } else if (message.startsWith(fsw)) {
                    //左侧摆动电机角度
                    frontSwingMotor = getValue(message);
                    for (SparkForkCallback sparkForkCallback1 : sparkForkCallback) {
                        if (sparkForkCallback1 != null) {
                            sparkForkCallback1.onFrontSwingMotor(frontSwingMotor);
                        }
                    }
                } else if (message.startsWith(BSW)) {
                    backSwingMotor = getValue(message);
                    //右侧摆动电机角度
                    for (SparkForkCallback sparkForkCallback1 : sparkForkCallback) {
                        if (sparkForkCallback1 != null) {
                            sparkForkCallback1.onBackSwingMotor(backSwingMotor);
                        }
                    }
                } else if (message.startsWith(FSP)) {
                    frontSpark = getValue(message);
                    //前侧火花状态
                    for (SparkForkCallback sparkForkCallback1 : sparkForkCallback) {
                        if (sparkForkCallback1 != null) {
                            sparkForkCallback1.onFrontSpark(frontSpark);
                        }
                    }
                } else if (message.startsWith(BSP)) {
                    backSpark = getValue(message);
                    //后侧火花状态
                    for (SparkForkCallback sparkForkCallback1 : sparkForkCallback) {
                        if (sparkForkCallback1 != null) {
                            sparkForkCallback1.onBackSpark(backSpark);
                        }
                    }
                } else if (message.startsWith(VALID)) {
                    validTestValue = getValue(message);
                    //检测值有效定义
                    for (SparkForkCallback sparkForkCallback1 : sparkForkCallback) {
                        if (sparkForkCallback1 != null) {
                            sparkForkCallback1.onValidTestValue(validTestValue);
                        }
                    }
                } else if (message.startsWith(OUT)) {
                    outIndex = getValue(message);
                    //外侧当前绝缘子位置
                } else if (message.startsWith(IN)) {
                    inIndex = getValue(message);
                    //内侧当前绝缘子位置
                } else if (message.startsWith(ALM)) {
                    String value = getValue(message);
                    String[] split1 = value.split(DOU);
                    if (split1.length != 2) {
                        return;
                    }
                    alarmInfo = getAlarmInfo(split1[0], split1[1], message);
                    if (alarmInfo == null) {
                        return;
                    }
                    if (alarmInfo.isHas()) {
                        alarmInfoMap.put(alarmInfo.getKey(), alarmInfo);
                    } else {
                        alarmInfoMap.remove(alarmInfo.getKey());
                    }
                    AlarmUtils.print(alarmInfo);
                    for (AlarmCallback alarmCallback1 : alarmCallback) {
                        if (alarmCallback1 != null) {
                            alarmCallback1.onAlarm(alarmInfo);
                        }
                    }
                } else if (message.startsWith(INFO)) {
                    infoValue = getValue(message);
                    //配置参数起始、结束标志：1－开始；0－结束
                    for (AlarmCallback alarmCallback1 : alarmCallback) {
                        alarmCallback1.onInfo(Protocol.getInfo(infoValue));
                    }
                } else if (message.startsWith(SWI)) {
                    swingInside = getValue(message);
                    //探针摆动到内侧设定值
                } else if (message.startsWith(SWO)) {
                    swingOutside = getValue(message);
                    //探针摆动到外侧侧设定值
                } else if (message.startsWith(STA)) {
                    taskState = getValue(message);
                    //任务状态
                } else if (message.startsWith(LOG)) {
                } else if (message.startsWith(TMP)) {
                    boardTemperature = getValue(message);
                    //板卡温度
                    for (RobotCallback robotCallback1 : robotCallback) {
                        robotCallback1.onBoardTemperature(boardTemperature);
                    }
                } else if (message.startsWith(PITCH)) {
                    pitchValue = getValue(message);
                    for (RobotCallback robotCallback1 : robotCallback) {
                        robotCallback1.onPitch(pitchValue);
                    }
                } else if (message.startsWith(ROLL)) {
                    rollValue = getValue(message);
                    for (RobotCallback robotCallback1 : robotCallback) {
                        robotCallback1.onRoll(rollValue);
                    }
                } else if (message.startsWith(YAW)) {
                    yawValue = getValue(message);
                    for (RobotCallback robotCallback1 : robotCallback) {
                        robotCallback1.onYaw(yawValue);
                    }
                } else if (message.startsWith(ADJ)) {
                    LogUtil.e(TAG, "handleMessage: adj " + data);
                    adjValue = getValue(message);
                    //配置参数起始、结束标志：1－开始；0－结束
                    for (ConfigCallback configCallback1 : configCallback) {
                        configCallback1.onState(adjValue);
                    }
                } else if (message.startsWith(BAT_SOC)) {
                    //机器人电量
                    String value = getValue(message);
                    if (TextUtils.isEmpty(value)) {
                        return;
                    }
                    battery = Integer.parseInt(value);
                    for (BatteryCallback batteryCallback : batteryCallbacks) {
                        batteryCallback.onBattery(battery);
                    }
                }else if (message.startsWith(BAT_VOLT)) {
                    //电池电压
                    batteryVolt = getValue(message);
                    for (BatteryCallback batteryCallback : batteryCallbacks) {
                        batteryCallback.onVoltage(batteryVolt);
                    }
                }else if (message.startsWith(BAT_CUR)) {
                    //电池电流
                    batteryCur = getValue(message);
                    for (BatteryCallback batteryCallback : batteryCallbacks) {
                        batteryCallback.onCurrent(batteryCur);
                    }
                }else if (message.startsWith(BAT_SOH)) {
                    //电池健康度
                    batterySoh = getValue(message);
                    for (BatteryCallback batteryCallback : batteryCallbacks) {
                        batteryCallback.onHealthy(batterySoh);
                    }
                }else if (message.startsWith(BAT_TEMP)) {
                    //电芯温度
                    batteryCellTemp = getValue(message);
                    for (BatteryCallback batteryCallback : batteryCallbacks) {
                        batteryCallback.onCellTemperature(batteryCellTemp);
                    }
                }else if (message.startsWith(BAT_MOS)) {
                    //电芯温度
                    batteryMOSTemp = getValue(message);
                    for (BatteryCallback batteryCallback : batteryCallbacks) {
                        batteryCallback.onMOSTemperature(batteryMOSTemp);
                    }
                }else if (message.startsWith(BAT_CIRCLE)) {
                    //充放电次数
                    batteryCount = getValue(message);
                    for (BatteryCallback batteryCallback : batteryCallbacks) {
                        batteryCallback.onCount(batteryCount);
                    }
                }else if (message.startsWith(BAT_STATIC1)) {
                    //bms系统状态1
                    batteryState1 = getValue(message);
                    for (BatteryCallback batteryCallback : batteryCallbacks) {
                        batteryCallback.onBMSSystem1(batteryState1);
                    }
                }else if (message.startsWith(BAT_STATIC2)) {
                    //bms系统状态2
                    batteryState2 = getValue(message);
                    for (BatteryCallback batteryCallback : batteryCallbacks) {
                        batteryCallback.onBMSSystem2(batteryState2);
                    }
                }else if (message.startsWith(BAT_VOL1)) {
                    //电芯1电压
                    batteryVol1 = getValue(message);
                    for (BatteryCallback batteryCallback : batteryCallbacks) {
                        batteryCallback.onCellVoltage1(batteryVol1);
                    }
                }else if (message.startsWith(BAT_VOL2)) {
                    //电芯2电压
                    batteryVol2 = getValue(message);
                    for (BatteryCallback batteryCallback : batteryCallbacks) {
                        batteryCallback.onCellVoltage2(batteryVol2);
                    }
                }else if (message.startsWith(BAT_VOL3)) {
                    //电芯3电压
                    batteryVol3 = getValue(message);
                    for (BatteryCallback batteryCallback : batteryCallbacks) {
                        batteryCallback.onCellVoltage3(batteryVol3);
                    }
                }else if (message.startsWith(BAT_VOL4)) {
                    //电芯4电压
                    batteryVol4 = getValue(message);
                    for (BatteryCallback batteryCallback : batteryCallbacks) {
                        batteryCallback.onCellVoltage4(batteryVol4);
                    }
                }else if (message.startsWith(SETDATA)) {
                    //转速调整比例
                    String value = getValue(message);
                    if (TextUtils.isEmpty(value)) {
                        return;
                    }
                    String[] split1 = value.split(HENG);
                    if (split1 == null || split1.length <= 0) {
                        return;
                    }
                    for (int i = 0; i < split1.length; i++) {
                        String s = split1[i];
                        if (TextUtils.isEmpty(s)) {
                            continue;
                        }
                        String[] split2 = s.split(DOU);
                        if (split2 == null || split2.length != 2) {
                            continue;
                        }
                        if (one.equals(split2[0])) {
                            //软件版本号
                        } else if (two.equals(split2[0])) {
                            //摆动电机0角度配置
                            ssw0Value = split2[1];
                            for (SwingAngleCallback swingAngleCallback1 : swingAngleCallback) {
                                swingAngleCallback1.onZero(ssw0Value);
                            }
                        } else if (three.equals(split2[0])) {
                            //摆动电机1角度配置
                            ssw1Value = split2[1];
                            for (SwingAngleCallback swingAngleCallback1 : swingAngleCallback) {
                                swingAngleCallback1.onOne(ssw1Value);
                            }
                        } else if (four.equals(split2[0])) {
                            //摆动电机2角度配置
                            ssw2Value = split2[1];
                            for (SwingAngleCallback swingAngleCallback1 : swingAngleCallback) {
                                swingAngleCallback1.onTwo(ssw2Value);
                            }
                        } else if (five.equals(split2[0])) {
                            //摆动电机3角度配置
                            ssw3Value = split2[1];
                            for (SwingAngleCallback swingAngleCallback1 : swingAngleCallback) {
                                swingAngleCallback1.onThree(ssw3Value);
                            }
                        } else if (six.equals(split2[0])) {
                            //转速比
                            rateValue = split2[1];
                            for (SpeedRatioCallback speedRatioCallback1 : speedRatioCallback) {
                                speedRatioCallback1.onSpeedRatio(rateValue);
                            }
                        } else if (seven.equals(split2[0])) {
                            cameraOut = split2[1];
                            for (CameraCallback cameraCallback1 : cameraCallback) {
                                cameraCallback1.onOut(cameraOut);
                            }
                        } else if (eight.equals(split2[0])) {
                            cameraMid = split2[1];
                            for (CameraCallback cameraCallback1 : cameraCallback) {
                                cameraCallback1.onMid(cameraMid);
                            }
                        } else if (nine.equals(split2[0])) {
                            cameraIn = split2[1];
                            for (CameraCallback cameraCallback1 : cameraCallback) {
                                cameraCallback1.onIn(cameraIn);
                            }
                        }
                    }

                }
            }
        }
    }


    private String getValue(String message) {
        String[] split1 = message.split(MAOHAO);
        if (split1.length == 2) {
            return split1[1];
        }
        return "";
    }

    public boolean init() {
        LogUtil.e(TAG, "init " + isInit.get());
        if (isInit.get()) {
            return true;
        }
        robotSerialManager = new RobotSerialManager();
        boolean open = robotSerialManager.open("/dev/ttyHS0", 115200, messageCallback);
        if (open) {
            isInit.set(true);
        }
        if (handler != null) {
            handler.sendEmptyMessageDelayed(timeWhat, timeDelay);
        }
        return open;
    }


    public void close() {
        if (isInit.get()) {
            robotSerialManager.close();
            leftSpeed = null;
            rightSpeed = null;
            frontLaserRanging = null;
            backLaserRanging = null;
            frontSwingMotor = null;
            backSwingMotor = null;
            frontSpark = null;
            backSpark = null;
            boardTemperature = null;
            outIndex = null;
            inIndex = null;
            alarmInfo = null;
            swingInside = null;
            swingOutside = null;
            validTestValue = null;
            rateValue = null;
            ssw0Value = null;
            ssw1Value = null;
            ssw2Value = null;
            ssw3Value = null;
            alarmInfoMap.clear();
        }
    }

    public void setLogcallback(LogCallback logcallback) {
        if (robotSerialManager != null) {
            robotSerialManager.setLogCallback(logcallback);
        }
    }

    public void removeLogCallback() {
        if (robotSerialManager != null) {
            robotSerialManager.removeLogCallback();
        }
    }

    public void addMoveSpeedCallback(MoveSpeedCallback moveSpeedCallback) {
        LogUtil.e(TAG, "addMoveSpeedCallback: ");
        if (this.moveSpeedCallback.contains(moveSpeedCallback)){
            return;
        }
        this.moveSpeedCallback.add(moveSpeedCallback);
    }

    public void removeMoveSpeedCallback(MoveSpeedCallback moveSpeedCallback) {
        LogUtil.e(TAG, "removeMoveSpeedCallback: ");
        this.moveSpeedCallback.remove(moveSpeedCallback);
    }


    public void addLaserRangingCallback(LaserRangingCallback laserRangingCallback) {
        LogUtil.e(TAG, "addLaserRangingCallback: ");
        if (this.laserRangingCallback.contains(laserRangingCallback)){
            return;
        }
        this.laserRangingCallback.add(laserRangingCallback);
    }

    public void removeLaserRangingCallback(LaserRangingCallback laserRangingCallback) {
        LogUtil.e(TAG, "removeLaserRangingCallback: ");
        this.laserRangingCallback.remove(laserRangingCallback);
    }


    public void addSparkForkCallback(SparkForkCallback sparkForkCallback) {
        LogUtil.e(TAG, "addSparkForkCallback: ");
        if (this.sparkForkCallback.contains(sparkForkCallback)){
            return;
        }
        this.sparkForkCallback.add(sparkForkCallback);
    }

    public void removeSparkForkCallback(SparkForkCallback sparkForkCallback) {
        LogUtil.e(TAG, "removeSparkForkCallback: ");
        this.sparkForkCallback.remove(sparkForkCallback);
    }


    public void addRobotCallback(RobotCallback robotCallback) {
        LogUtil.e(TAG, "addRobotCallback: ");
        if (this.robotCallback.contains(robotCallback)){
            return;
        }
        this.robotCallback.add(robotCallback);
    }

    public void removeRobotCallback(RobotCallback robotCallback) {
        LogUtil.e(TAG, "removeRobotCallback: ");
        this.robotCallback.remove(robotCallback);
    }


    public void addAlarmCallback(AlarmCallback alarmCallback) {
        LogUtil.e(TAG, "addAlarmCallback: ");
        if (this.alarmCallback.contains(alarmCallback)){
            return;
        }
        this.alarmCallback.add(alarmCallback);
    }

    public void removeAlarmCallback(AlarmCallback alarmCallback) {
        LogUtil.e(TAG, "removeAlarmCallback: ");
        this.alarmCallback.remove(alarmCallback);
    }


    public void addSwingAngleCallback(SwingAngleCallback swingAngleCallback) {
        LogUtil.e(TAG, "addSwingAngleCallback: ");
        if (this.swingAngleCallback.contains(swingAngleCallback)){
            return;
        }
        this.swingAngleCallback.add(swingAngleCallback);
    }

    public void removeSwingAngleCallback(SwingAngleCallback swingAngleCallback) {
        LogUtil.e(TAG, "removeSwingAngleCallback: ");
        this.swingAngleCallback.remove(swingAngleCallback);
    }

    public void addSpeedRatioCallback(SpeedRatioCallback speedRatioCallback) {
        LogUtil.e(TAG, "setSpeedRatioCallback: ");
        if (this.speedRatioCallback.contains(speedRatioCallback)){
            return;
        }
        this.speedRatioCallback.add(speedRatioCallback);
    }

    public void removeSpeedRatioCallback(SpeedRatioCallback speedRatioCallback) {
        LogUtil.e(TAG, "removeSpeedRatioCallback: ");
        this.speedRatioCallback.remove(speedRatioCallback);
    }

    @Override
    public void addCameraCallback(CameraCallback cameraCallback) {
        LogUtil.e(TAG, "addCameraCallback: ");
        if (this.cameraCallback.contains(cameraCallback)){
            return;
        }
        this.cameraCallback.add(cameraCallback);
    }

    @Override
    public void removeCamareCallback(CameraCallback cameraCallback) {
        LogUtil.e(TAG, "removeCamareCallback: ");
        this.cameraCallback.remove(cameraCallback);
    }

    @Override
    public void addConfigCallback(ConfigCallback configCallback) {
        LogUtil.e(TAG, "addConfigCallback: ");
        if (this.configCallback.contains(configCallback)){
            return;
        }
        this.configCallback.add(configCallback);
    }

    @Override
    public void addBatteryCallback(BatteryCallback batteryCallback) {
        LogUtil.e(TAG, "addBatteryCallback: ");
        if (this.batteryCallbacks.contains(batteryCallback)){
            return;
        }
        this.batteryCallbacks.add(batteryCallback);
    }

    @Override
    public void removeBatteryCallback(BatteryCallback batteryCallback) {
        LogUtil.e(TAG, "removeBatteryCallback: ");
        this.batteryCallbacks.remove(batteryCallback);
    }

    @Override
    public void removeConfigCallback(ConfigCallback configCallback) {
        LogUtil.e(TAG, "removeConfigCallback: ");
        this.configCallback.remove(configCallback);
    }

    public boolean isConnect() {
        return isConnect.get();
    }

    public void startConfig() {
        Log.e(TAG, "startConfig: isConnect:" + isConnect.get() + "    isInit:" + isInit.get());
        if (!isConnect.get()) {
            return;
        }
        if (!isInit.get()) {
            return;
        }

        robotSerialManager.send(new StringBuilder(TAG_START).append(GET).append(MAOHAO).append(one).append(TAG_END).toString().getBytes(StandardCharsets.UTF_8));
    }
    public void endConfig(){
        Log.e(TAG, "endConfig: isConnect:" + isConnect.get() + "    isInit:" + isInit.get());
        if (!isConnect.get()) {
            return;
        }
        if (!isInit.get()) {
            return;
        }
        robotSerialManager.send(new StringBuilder(TAG_START).append(GET).append(MAOHAO).append(two).append(TAG_END).toString().getBytes(StandardCharsets.UTF_8));
    }

    public void setSsw0(int ssw0) {
        LogUtil.e(TAG, "setSsw0: " + ssw0);
        sendConfig(2,String.valueOf(ssw0));
    }

    public void setSsw1(int ssw1) {
        LogUtil.e(TAG, "setSsw1: " + ssw1);
        sendConfig(3,String.valueOf(ssw1));
    }

    public void setSsw2(int ssw2) {
        LogUtil.e(TAG, "setSsw2: " + ssw2);
        sendConfig(4,String.valueOf(ssw2));
    }

    public void setSsw3(int ssw3) {
        LogUtil.e(TAG, "setSsw3: " + ssw3);
        sendConfig(5,String.valueOf(ssw3));
    }

    public void setRate(int rate) {
        LogUtil.e(TAG, "setRate: " + rate);
        sendConfig(6, String.valueOf(rate));
    }
    public void setCameraOutAngle(int angle) {
        LogUtil.e(TAG, "setCameraOutAngle: " + angle);
        sendConfig(7,String.valueOf(angle));
    }
    public void setCameraMidAngle(int angle) {
        LogUtil.e(TAG, "setCameraMidAngle: " + angle);
        sendConfig(8,String.valueOf(angle));
    }
    public void setCameraInAngle(int angle) {
        LogUtil.e(TAG, "setCameraInAngle: " + angle);
        sendConfig(9,String.valueOf(angle));
    }
    public void setMaxSpeed(int maxSpeed) {
        LogUtil.e(TAG, "setMaxSpeed: " + maxSpeed);
        sendConfig(10, String.valueOf(maxSpeed));
    }
}
